// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: linchuan

#include "coin2/exchange/kraken/api_order/native_rest_async_asio_subscriber.h"

#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <thread>

#include <nlohmann/json.hpp>

#include "coin2/base/log.h"

namespace coin2::exchange::kraken::api_order {

void KrakenRestAsyncAsioSubscriber::QueryBalance() {
  auto http_context = rest_client()->QueryAccountBalance();
  http_context->handler =
      std::bind(&KrakenRestAsyncAsioSubscriber::HandleQuery, this, std::placeholders::_1);
  http_driver_->PostAsyncContext(http_context);
}

void KrakenRestAsyncAsioSubscriber::QueryOpenOrders() {
  auto http_context = rest_client()->QueryOpenOrders();
  http_context->handler =
      std::bind(&KrakenRestAsyncAsioSubscriber::HandleQuery, this, std::placeholders::_1);
  http_driver_->PostAsyncContext(http_context);
}

void KrakenRestAsyncAsioSubscriber::QueryDoneOrders() {
  auto http_context = rest_client()->QueryClosedOrders();
  http_context->handler =
      std::bind(&KrakenRestAsyncAsioSubscriber::HandleQuery, this, std::placeholders::_1);
  http_driver_->PostAsyncContext(http_context);
}

void KrakenRestAsyncAsioSubscriber::QueryFills() {
  auto http_context = rest_client()->QueryTrades();
  http_context->handler =
      std::bind(&KrakenRestAsyncAsioSubscriber::HandleQuery, this, std::placeholders::_1);
  http_driver_->PostAsyncContext(http_context);
}

void KrakenRestAsyncAsioSubscriber::QueryWsToken() {
  auto http_context = rest_client()->GetWsToken();
  http_context->handler =
      std::bind(&KrakenRestAsyncAsioSubscriber::HandleQuery, this, std::placeholders::_1);
  http_driver_->PostAsyncContext(http_context);
}

void KrakenRestAsyncAsioSubscriber::SubscribeAsync() {
  AddPeriodicTask(
      std::bind(&KrakenRestAsyncAsioSubscriber::QueryWsToken, this),
      600,
      "gen_ws_token");

  AddPeriodicTask(
      std::bind(&KrakenRestAsyncAsioSubscriber::QueryBalance, this),
      config_.query_account_balance_period_sec(),
      "query_balance");

  AddPeriodicTask(
      std::bind(&KrakenRestAsyncAsioSubscriber::QueryOpenOrders, this),
      config_.query_open_orders_period_sec(),
      "query_open_orders");

  AddPeriodicTask(
      std::bind(&KrakenRestAsyncAsioSubscriber::QueryDoneOrders, this),
      config_.query_cancel_orders_period_sec(),
      "query_all_orders");

  AddPeriodicTask(
      std::bind(&KrakenRestAsyncAsioSubscriber::QueryFills, this),
      config_.query_fill_period_sec(),
      "query_fills");
}

}  // namespace coin2::exchange::kraken::api_order
